[Coding023] Sort - 选择排序

堆排序

Ben 2024/01/07

More coding records

Get the knowledge flowing and circulating! :)

目录

标题:堆排序

堆排序(英语:Heapsort)是指利用这种数据结构所设计的一种排序算法

是一个近似完全二叉树的结构,并同时满足堆的性质:即子节点的键值或索引总是小于(或者大于)它的父节点。

img

Fig. 堆排序算法的演示。
首先,将元素进行重排,以符合堆的条件。图中排序过程之前简单地绘出了堆树的结构。

若以升序排序说明,把数组转换成最大堆(Max-Heap Heap)。

  • 这是一种满足最大堆性质(Max-Heap Property)的二叉树:对于除了根之外的每个节点i, A[parent(i)] ≥ A[i]。

重复从最大堆取出数值最大的结点(把根结点和最后一个结点交换,把交换后的最后一个结点移出堆),并让残余的堆维持最大堆性质。

堆节点的访问

通常堆是通过一维数组来实现的。在数组起始位置为0的情形中:

  • 父节点i的左子节点在位置(2i+1)

  • 父节点i的右子节点在位置(2i+2)

  • 子节点i的父节点在位置(i1)/2

    • 向上取整 x - $\lceil x \rceil$

    • 向下取整 x - $\lfloor x \rfloor$

在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。堆中定义以下几种操作:

  • 最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点

  • 建立最大堆(Build Max Heap):将堆中的所有数据重新排序

  • 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算

——维基百科

堆排序基础

image-20240107194006536

涉及知识点

image-20240107194055878

image-20240107194118312

堆排序思想步骤解读(手绘示意图)

image-20240107194443295

一次完整的排序手绘图

image-20240107200050520

▲ 特殊情况注意(这种情况不会存在的!

image-20240107200411137

image-20240107201133201

另一个直观的例子

image-20240107201547523

heapsort_Animation

C语言代码实现

运行结果

image-20240107195236293

复杂度

平均时间复杂度Θ(nlogn)
最坏时间复杂度O(nlogn)
最优时间复杂度O(nlogn)
空间复杂度总共O(n),需要辅助空间O(1)
最佳解不是

堆排序的稳定性

image-20240107194613935